package com.foodapp.back.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foodapp.back.dto.LoginDTO;
import com.foodapp.back.dto.RegisterDTO;
import com.foodapp.back.entity.User;
import com.foodapp.back.exception.ApiException;
import com.foodapp.back.mapper.UserMapper;
import com.foodapp.back.service.UserService;
import com.foodapp.back.util.JwtTokenUtil;
import com.foodapp.back.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public Map<String, Object> login(LoginDTO loginDTO) {
        // 根据用户名查询用户
        User user = getByUsername(loginDTO.getUsername());
        if (user == null) {
            // 尝试通过手机号查询
            user = getByPhone(loginDTO.getUsername());
            if (user == null) {
                // 尝试通过邮箱查询
                user = getByEmail(loginDTO.getUsername());
                if (user == null) {
                    throw new ApiException("用户不存在");
                }
            }
        }

        // 校验密码
        if (!BCrypt.checkpw(loginDTO.getPassword(), user.getPassword())) {
            throw new ApiException("密码错误");
        }

        // 校验用户状态
        if (user.getStatus() == 0) {
            throw new ApiException("账号已被禁用");
        }

        // 生成token
        String token = jwtTokenUtil.generateToken(user.getUsername(), user.getId(), user.getRole());

        // 组装返回数据
        Map<String, Object> result = new HashMap<>();
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        result.put("token", token);
        result.put("userInfo", userVO);

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(RegisterDTO registerDTO) {
        // 校验两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            throw new ApiException("两次密码不一致");
        }

        // 校验用户名是否已存在
        if (getByUsername(registerDTO.getUsername()) != null) {
            throw new ApiException("用户名已存在");
        }

        // 校验手机号是否已存在
        if (registerDTO.getPhone() != null && getByPhone(registerDTO.getPhone()) != null) {
            throw new ApiException("手机号已被注册");
        }

        // 校验邮箱是否已存在
        if (registerDTO.getEmail() != null && getByEmail(registerDTO.getEmail()) != null) {
            throw new ApiException("邮箱已被注册");
        }

        // 创建用户
        User user = new User();
        BeanUtils.copyProperties(registerDTO, user);
        
        // 加密密码
        user.setPassword(BCrypt.hashpw(registerDTO.getPassword()));
        
        // 设置默认值
        user.setRole("user");
        user.setStatus(1);
        user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        user.setIsDeleted(0);

        return save(user);
    }

    @Override
    public UserVO getUserInfo(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new ApiException("用户不存在");
        }

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserInfo(Long userId, UserVO userVO) {
        User user = getById(userId);
        if (user == null) {
            throw new ApiException("用户不存在");
        }

        // 不允许修改敏感字段
        user.setRealName(userVO.getRealName());
        user.setAvatar(userVO.getAvatar());
        
        // 如果修改了手机号，校验是否已存在
        if (!user.getPhone().equals(userVO.getPhone())) {
            if (getByPhone(userVO.getPhone()) != null) {
                throw new ApiException("手机号已被注册");
            }
            user.setPhone(userVO.getPhone());
        }
        
        // 如果修改了邮箱，校验是否已存在
        if (!user.getEmail().equals(userVO.getEmail())) {
            if (getByEmail(userVO.getEmail()) != null) {
                throw new ApiException("邮箱已被注册");
            }
            user.setEmail(userVO.getEmail());
        }

        return updateById(user);
    }

    @Override
    public User getByUsername(String username) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        return getOne(wrapper);
    }

    @Override
    public User getByPhone(String phone) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        return getOne(wrapper);
    }

    @Override
    public User getByEmail(String email) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail, email);
        return getOne(wrapper);
    }
}
